﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Script.Serialization;
using System.Web.Script.Services;
using System.Web.Services;
using System.Web.UI;
using System.Web.UI.WebControls;
using MLM.AdminCP.Class;
using Telerik.Web.UI;
using MLM.Data;

namespace MLM.AdminCP.Pages
{
    public partial class BonusDetailByMonth : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            int thisYear = Convert.ToInt32(System.DateTime.Now.Year);
            for (int i = 2013; i <= thisYear; i++)
            {
                FromYearCbb.Items.Add(new RadComboBoxItem(i.ToString(), i.ToString()));
            }
            for (int i = 1; i < 13; i++)
            {
                MonthCbb.Items.Add(new RadComboBoxItem(i.ToString(), i.ToString()));
            }
        }
        [WebMethod]
        [ScriptMethod(ResponseFormat = ResponseFormat.Json)]
        public static string GetOwnPv(string _userId, string _year, string _month)
        {
            long userId = long.Parse(_userId);
            int year = int.Parse(_year);
            int month = int.Parse(_month);
            MLMDataContext ct = new MLMDataContext();
            User user = ct.Users.FirstOrDefault(it => it.UserId == userId);
            UserInfo info = new UserInfo();
            var minDate = new DateTime(year, month, 1, 0, 0, 0);// from start date of a month
            var maxDate = new DateTime(year, month,
                                       DateTime.DaysInMonth(year, month), 23, 59, 0);// to end date of a month


            if (user != null)
            {
                info.UserId = user.UserId;
                info.Name = user.FirstName + " " + user.LastName;
                var mySell =
                       ct.Invoices.Where(
                           it =>
                           it.UserID == user.UserId && it.DateTimeCreated >= minDate && it.DateTimeCreated <= maxDate && it.Status == 1);
                // get all my invoice (order) where i buy. // 
                double? myOwnPoint = 0;
                double? myTotalPoint = 0;
                double? myOwnSelling = 0;
                foreach (var invoice in mySell)
                {
                    var invoiceDetails = ct.InvoiceDetails.Where(it => it.InvoiceID == invoice.InvoiceID);
                    foreach (var invoiceDetail in invoiceDetails)
                    {
                        if (user.RoleID != 2 && user.RoleID != 3)
                        {
                            myOwnPoint += invoiceDetail.Point * invoiceDetail.Quantity;
                            myTotalPoint += invoiceDetail.Point * invoiceDetail.Quantity;
                            myOwnSelling += invoiceDetail.Price * invoiceDetail.Quantity;
                        }
                        
                    }
                }
                List<RecommendUserInfo> recommendUser = new List<RecommendUserInfo>();
                var sponsorList = ct.Users.Where(it => it.SponsorID == userId);
                foreach (var sponsoritem in sponsorList)
                {
                    sponsorIds.Clear();
                    GetGroupSellings(ct, userId);
                    RecommendUserInfo sponsorSelling = new RecommendUserInfo();
                    long sponsorPoint = 0;
                    double? sponsorSale = 0;
                    //my own point

                    foreach (var item in ct.Invoices.Where(p => p.UserID == sponsoritem.UserId && p.Status == 1 && p.DateTimeCreated >= minDate && p.DateTimeCreated <= maxDate))
                    {
                        var _point = ct.InvoiceDetails.Where(p => p.InvoiceID == item.InvoiceID);
                        if (_point.Count() > 0)
                        {
                            foreach (var a in _point)
                            {
                                if (sponsoritem.RoleID != 2 && sponsoritem.RoleID != 3)
                                {
                                    sponsorPoint += long.Parse(a.Point.ToString()) * long.Parse(a.Quantity.ToString());
                                    sponsorSale += a.Price * a.Quantity;
                                }
                            }
                        }
                    }

                    //all group
                    foreach (var sponsorId in sponsorIds)
                    {
                        var sponsor = ct.Users.FirstOrDefault(it => it.UserId == sponsorId);
                        foreach (var item in ct.Invoices.Where(p => p.UserID == sponsor.UserId && p.Status == 1 && p.DateTimeCreated >= minDate && p.DateTimeCreated <= maxDate))
                        {
                            var _point = ct.InvoiceDetails.Where(p => p.InvoiceID == item.InvoiceID);
                            if (_point.Count() > 0)
                            {
                                foreach (var a in _point)
                                {
                                    if (user.RoleID != 2 && user.RoleID != 3)
                                    {
                                        myTotalPoint += long.Parse(a.Point.ToString()) * long.Parse(a.Quantity.ToString());
                                        //   sponsorSale += a.Price * a.Quantity;    
                                    }

                                }
                            }
                        }
                    }
                    if (sponsoritem.RoleID != 2 && sponsoritem.RoleID != 3)
                    {
                        sponsorSelling.Point = sponsorPoint;
                        sponsorSelling.Bonus = ct.Ranks.Where(it => it.MinPV <= sponsorPoint).Max(it => it.Bonus) ?? 0;
                        sponsorSelling.Selling = Double.Parse(Math.Round(decimal.Parse(sponsorSale.ToString()), 2) + "");
                    }
                    else
                    {
                        sponsorSelling.Point = 0;
                        sponsorSelling.Bonus = 0;
                        sponsorSelling.Selling = 0;
                    }

                    sponsorSelling.UserId = sponsoritem.UserId;
                    sponsorSelling.Name = sponsoritem.FirstName + " " + sponsoritem.LastName;
                    // myTotalPoint += sponsorPoint;
                    recommendUser.Add(sponsorSelling);
                }


                if (user.RoleID != 2 && user.RoleID != 3)               
                {
                    info.Selling = Double.Parse(Math.Round(decimal.Parse(myOwnSelling.ToString()), 2) + "");
                    info.Point = myOwnPoint;
                    info.Bonus = ct.Ranks.Where(it => it.MinPV <= myOwnPoint).Max(it => it.Bonus) ?? 0;
                }
                else
                {
                    info.Point = 0;
                    info.Bonus = 0;
                    info.Selling = 0;
                }
                info.RecommendUser = recommendUser;
                info.CarrierBonus = GetCarrierBonus(ct, userId, year, month);

            }
            JavaScriptSerializer ser = new JavaScriptSerializer();
            return ser.Serialize(info);
        }
        public static List<long> sponsorIds = new List<long>();
        public static void GetGroupSellings(MLMDataContext ct, long userId)
        {
            var sponsorList = ct.Users.Where(it => it.SponsorID == userId);
            foreach (var sponsor in sponsorList)
            {
                sponsorIds.Add(sponsor.UserId);
                GetGroupSellings(ct, sponsor.UserId);
            }
        }
        public class UserInfo
        {
            public long UserId { get; set; }
            public string Name { get; set; }
            public double? Point { get; set; }
            public double? Bonus { get; set; }
            public double? Selling { get; set; }
            public double? SaleHeadBonusConfig { get; set; }
            public List<RecommendUserInfo> RecommendUser { get; set; }
            public CarrierBonusInfo CarrierBonus { get; set; }
        }
        public class RecommendUserInfo
        {
            public long UserId { get; set; }
            public string Name { get; set; }
            public double? Point { get; set; }
            public double? Bonus { get; set; }
            public double? Selling { get; set; }
        }
        public class CarrierBonusInfo
        {
            public double? Bonus { get; set; }
            public int NumberOfSalesHead { get; set; }
            public int? NumberOfSalesHeadToGetFullBonus { get; set; }
            public int? NumberOfSalesHeadToGetMinBonus { get; set; }
            public int? MinPVRequire { get; set; }
        }
        public static CarrierBonusInfo GetCarrierBonus(MLMDataContext ct, long userId, int year, int month)
        {
            CarrierBonusInfo carrierBonusInfo = new CarrierBonusInfo();
            var sponsorList = ct.Users.Where(it => it.SponsorID == userId).ToList();
            var CarrierBonusConfig = ct.CarrierBonusConfigs.OrderByDescending(it => it.NumberOfRankRequire);
            var startDay = new DateTime(year, month, 1, 0, 0, 0);
            var endDay = new DateTime(year, month, DateTime.DaysInMonth(year, month), 23, 59, 0);
            double? totalBonus = 0;
            var myOwnInfo = ct.Users.FirstOrDefault(it => it.UserId == userId);
            foreach (var bonusConfig in CarrierBonusConfig)
            {
                var salesHeadCount = 0;
                //my point
                long myPoint = 0;
                foreach (
                    var item in
                        ct.Invoices.Where(
                            p =>
                            p.UserID == userId && p.Status == 1 && p.DateTimeCreated >= startDay &&
                            p.DateTimeCreated <= endDay)) //datetimecreated...
                {
                    var _point = ct.InvoiceDetails.Where(p => p.InvoiceID == item.InvoiceID);
                    if (_point.Count() > 0)
                    {
                        foreach (var a in _point)
                        {
                            myPoint += long.Parse(a.Point.ToString()) * long.Parse(a.Quantity.ToString());
                        }
                    }
                }
                //sponsor point
                foreach (var user in sponsorList)
                {
                    long point = 0;
                    foreach (
                        var item in
                            ct.Invoices.Where(
                                p =>
                                p.UserID == user.UserId && p.Status != -1 && p.DateTimeCreated >= startDay &&
                                p.DateTimeCreated <= endDay)) //datetimecreated...
                    {
                        var _point = ct.InvoiceDetails.Where(p => p.InvoiceID == item.InvoiceID);
                        if (_point.Count() > 0)
                        {
                            foreach (var a in _point)
                            {
                                point += long.Parse(a.Point.ToString()) * long.Parse(a.Quantity.ToString());
                            }
                        }
                    }
                    myPoint += point;
                    if (point >= ct.Ranks.FirstOrDefault(it => it.RankID == bonusConfig.RankRequire).MinPV)
                    {
                        salesHeadCount++;
                    }
                }
                carrierBonusInfo.NumberOfSalesHeadToGetMinBonus = bonusConfig.NumberOfRankRequire;
                carrierBonusInfo.MinPVRequire = bonusConfig.MinPVRequire;
                carrierBonusInfo.NumberOfSalesHeadToGetFullBonus =
                    ct.CarrierBonusConfigs.OrderBy(it => it.NumberOfRankRequire).Where(it => it.NumberOfRankRequire > bonusConfig.NumberOfRankRequire).Min(
                        it => it.NumberOfRankRequire) - 1;
                carrierBonusInfo.NumberOfSalesHead = salesHeadCount;
                if (myOwnInfo.RoleID == 4) // just check if is distributor
                {
                    if (myPoint >= bonusConfig.MinPVRequire)
                    {
                        if (salesHeadCount >= bonusConfig.NumberOfRankRequire)
                        {
                            totalBonus += bonusConfig.Bonus;
                            break;
                        }
                        else
                        {
                            carrierBonusInfo.Bonus = 0;
                        }
                    }
                    else
                    {
                        carrierBonusInfo.Bonus = 0; //0%
                    }
                }
                else // 
                {
                    if (salesHeadCount >= bonusConfig.NumberOfRankRequire)
                    {
                        totalBonus += bonusConfig.Bonus;
                        break;
                    }
                    else
                    {
                        carrierBonusInfo.Bonus = 0;
                    }
                }

            }
            carrierBonusInfo.Bonus = totalBonus;
            return carrierBonusInfo;
        }
    }
}